키패드 누르기

NOTE

프로그래머스(카카오) Lv1 · 구현(좌표 매핑 + 맨해튼 거리) 키패드를 2차원 배열로 만들지 않고 숫자를 index → 좌표로 변환해 맨해튼 거리로 손을 고르는 문제. “값 → 좌표 변환” 패턴의 대표 예.

📝 문제

  • 키패드에서 1 4 7은 왼손, 3 6 9는 오른손, 2 5 8 0더 가까운 손(같으면 hand가 우세한 손)으로 누른다.
  • 왼손 시작은 *, 오른손 시작은 #. 누른 손의 순서를 L/R 문자열로 반환.

💡 접근

  • 키패드를 배열로 만들지 않는다. 각 숫자를 0~11 인덱스로 매핑한 뒤 좌표로 변환.
index:  0 1 2 / 3 4 5 / 6 7 8 / 9 10 11
매핑:   1→0  2→1  ...  0→10  *→9  #→11
  • 좌표 계산: row = index / 3, col = index % 3.
  • 맨해튼 거리: |fromRow - toRow| + |fromCol - toCol| = Math.abs(from/3 - to/3) + Math.abs(from%3 - to%3).

⌨️ 풀이

public String solution(int[] numbers, String hand) {
 
    StringBuilder answer = new StringBuilder();
 
    int left = 9;   // *
    int right = 11; // #
 
    for (int num : numbers) {
 
        int target = (num == 0) ? 10 : num - 1;
 
        if (target % 3 == 0) {          // 왼쪽 열: 1 4 7 *
            answer.append("L");
            left = target;
        } else if (target % 3 == 2) {   // 오른쪽 열: 3 6 9 #
            answer.append("R");
            right = target;
        } else {                        // 가운데 열: 거리 비교
            int leftDist = distance(left, target);
            int rightDist = distance(right, target);
 
            if (leftDist < rightDist) {
                answer.append("L");
                left = target;
            } else if (rightDist < leftDist) {
                answer.append("R");
                right = target;
            } else {
                if (hand.equals("left")) {
                    answer.append("L");
                    left = target;
                } else {
                    answer.append("R");
                    right = target;
                }
            }
        }
    }
 
    return answer.toString();
}
 
private int distance(int from, int to) {
    return Math.abs(from / 3 - to / 3) + Math.abs(from % 3 - to % 3);
}

⏱️ 복잡도

  • 시간: O(N)numbers를 한 번 순회, 좌표 조회는 계산이라 O(1).
  • 공간: O(1) (결과 문자열 제외).

📎 오답 노트 (원본 방식과 비교)

원본은 int[][] keypad 2차원 배열 + findXY() 탐색 + Map<String,Integer>로 좌표를 저장하는 방식이었다. 좌표 매핑(계산) 방식과 비교하면:

항목원본(배열+Map)Best Practice(계산)
좌표 저장Map 객체int index
좌표 찾기배열 탐색계산
좌표 조회O(12)O(1)
메모리Map 객체 생성primitive
코드 길이길다짧다

교훈: 키패드를 그대로 배열로 만들기보다 row = i/3, col = i%3데이터 구조를 단순화하는 것이 문제 의도. 게임판 이동·최단거리·시뮬레이션에서 재사용된다.


🔗 관련